package com.ruoyi.web.controller.common

import com.ruoyi.common.config.RuoYiConfig
import com.ruoyi.common.constant.Constants
import com.ruoyi.common.core.domain.AjaxResult
import com.ruoyi.common.utils.MyStringUtils
import com.ruoyi.common.utils.file.FileUploadUtils
import com.ruoyi.common.utils.file.FileUtils
import com.ruoyi.framework.config.ServerConfig
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.http.MediaType
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.multipart.MultipartFile
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

/**
 * 通用请求处理
 *
 * @author ruoyi
 */
@RestController
@RequestMapping("/common")
open class CommonController {

    @Autowired
    private lateinit var serverConfig: ServerConfig
    /**
     * 通用下载请求
     *
     * @param fileName 文件名称
     * @param delete 是否删除
     */
    @GetMapping("/download")
    open fun fileDownload(fileName: String, delete: Boolean, response: HttpServletResponse, request: HttpServletRequest?) {
        try {
            if (!FileUtils.checkAllowDownload(fileName)) {
                throw Exception(MyStringUtils.format("文件名称({})非法，不允许下载。 ", fileName))
            }
            val realFileName: String = System.currentTimeMillis().toString() + fileName.substring(fileName.indexOf("_") + 1)
            val filePath: String = RuoYiConfig.downloadPath + fileName
            response.contentType = MediaType.APPLICATION_OCTET_STREAM_VALUE
            FileUtils.setAttachmentResponseHeader(response, realFileName)
            FileUtils.writeBytes(filePath, response.outputStream)
            if (delete) {
                FileUtils.deleteFile(filePath)
            }
        } catch (e: Exception) {
            log.error("下载文件失败", e)
        }
    }

    /**
     * 通用上传请求（单个）
     */
    @PostMapping("/upload")
    @Throws(Exception::class)
    open  fun uploadFile(file: MultipartFile): AjaxResult {
        return try {
            // 上传文件路径
            val filePath: String = RuoYiConfig.uploadPath
            // 上传并返回新文件名称
            val fileName: String = FileUploadUtils.upload(filePath, file)
            val url: String = serverConfig.url + fileName
            val ajax: AjaxResult = AjaxResult.success()
            ajax["url"] = url
            ajax["fileName"] = fileName
            ajax["newFileName"] = FileUtils.getName(fileName)
            ajax["originalFilename"] = file.originalFilename as Any
            ajax
        } catch (e: Exception) {
            AjaxResult.error(e.message)
        }
    }

    /**
     * 通用上传请求（多个）
     */
    @PostMapping("/uploads")
    @Throws(Exception::class)
    open fun uploadFiles(files: List<MultipartFile>): AjaxResult {
        return try {
            // 上传文件路径
            val filePath: String = RuoYiConfig.uploadPath
            val urls = mutableListOf<String>()
            val fileNames= mutableListOf<String>()
            val newFileNames = mutableListOf<String>()
            val originalFilenames =mutableListOf<String>()
            for (file in files) {
                // 上传并返回新文件名称
                val fileName: String = FileUploadUtils.upload(filePath, file)
                val url: String = serverConfig.url + fileName
                urls.add(url)
                fileNames.add(fileName)
                newFileNames.add(FileUtils.getName(fileName))
                file.originalFilename?.let { originalFilenames.add(it) }
            }
            val ajax: AjaxResult = AjaxResult.success()
            ajax["urls"] = org.apache.commons.lang3.StringUtils.join(urls, FILE_DELIMETER)
            ajax["fileNames"] = org.apache.commons.lang3.StringUtils.join(fileNames, FILE_DELIMETER)
            ajax["newFileNames"] = org.apache.commons.lang3.StringUtils.join(newFileNames, FILE_DELIMETER)
            ajax["originalFilenames"] = org.apache.commons.lang3.StringUtils.join(originalFilenames, FILE_DELIMETER)
            ajax
        } catch (e: Exception) {
            AjaxResult.error(e.message)
        }
    }

    /**
     * 本地资源通用下载
     */
    @GetMapping("/download/resource")
    @Throws(Exception::class)
    open fun resourceDownload(resource: String, request: HttpServletRequest, response: HttpServletResponse) {
        try {
            if (!FileUtils.checkAllowDownload(resource)) {
                throw Exception(MyStringUtils.format("资源文件({})非法，不允许下载。 ", resource))
            }
            // 本地资源路径
            val localPath: String? = RuoYiConfig.profile
            // 数据库资源地址
            val downloadPath = localPath + org.apache.commons.lang3.StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX)
            // 下载名称
            val downloadName: String = org.apache.commons.lang3.StringUtils.substringAfterLast(downloadPath, "/")
            response.contentType = MediaType.APPLICATION_OCTET_STREAM_VALUE
            FileUtils.setAttachmentResponseHeader(response, downloadName)
            FileUtils.writeBytes(downloadPath, response.outputStream)
        } catch (e: Exception) {
            log.error("下载文件失败", e)
        }
    }

    companion object {
        private val log: Logger = LoggerFactory.getLogger(CommonController::class.java)
        private const val FILE_DELIMETER = ","
    }
}
